package com.hcc.flow.server.controller.sys;

import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hcc.flow.server.annotation.LogAnnotation;
import com.hcc.flow.server.common.constant.Constant;
import com.hcc.flow.server.common.model.ApiResult;
import com.hcc.flow.server.common.utils.CommUtil;
import com.hcc.flow.server.common.utils.StringUtilsV2;
import com.hcc.flow.server.dao.sys.DepDao;
import com.hcc.flow.server.model.common.LoginUser;
import com.hcc.flow.server.model.sys.Dep;
import com.hcc.flow.server.utils.UserUtil;
import com.hcc.flow.server.vo.sys.DepShordVO;
import com.hcc.flow.server.vo.sys.DepVO;
import com.hcc.flow.server.where.sys.DepWhere;

import io.swagger.annotations.ApiOperation;

/**
 * 部门管理
 * 
 * @author 韩长志 2019-11-19
 *
 */
@RestController
@RequestMapping("/deps")
public class DepController {

	@Autowired
	private DepDao depDao;

	@LogAnnotation
	@PostMapping
	@ApiOperation(value = "部门-保存")
	//@PreAuthorize("hasAuthority('sys:dep:add')")
	public ApiResult<?> save(@RequestBody Dep dep) {
		if (dep == null) {
			return ApiResult.error("部门数据不能为空");
		} 
		if (StringUtilsV2.isBlank(dep.getOrgId())) {
			return ApiResult.error("所属机构ID不能为空");
		} 
		if (StringUtilsV2.isBlank(dep.getDepName())) {
			return ApiResult.error("部门名不能为空");
		} 
		if (StringUtilsV2.isBlank(dep.getDepCode())) {
			return ApiResult.error("部门编码不能为空");
		}
		LoginUser loginUser = UserUtil.getLoginUser();
		dep.setCreateUserId(loginUser.getUserId());
		verifyForm(dep);
		Dep oldRole = depDao.getByDepCode(dep.getDepCode());
		if (oldRole != null) {
			return ApiResult.error("部门编码已存在");
		}
		depDao.save(dep);
		return ApiResult.ok();
	}

	@GetMapping("/{id}")
	@ApiOperation(value = "部门-根据id获取")
	//@PreAuthorize("hasAuthority('sys:dep:query')")
	public ApiResult<?> get(@PathVariable String id) {
		if(id == null){
			return ApiResult.error("要查询的id不能为空");
		}
    	return ApiResult.data(depDao.getById(id));
	}

	@LogAnnotation
	@PutMapping
	@ApiOperation(value = "部门-修改")
	//@PreAuthorize("hasAuthority('sys:dep:edit')")
	public ApiResult<?> update(@RequestBody Dep dep) {
		if (dep == null) {
			return ApiResult.error("部门数据不能为空");
		}
		if (StringUtilsV2.isBlank(dep.getDepId())) {
			return ApiResult.error("部门ID不能为空");
		} 
		if (dep.getDepId().equals(dep.getParentId())) {
			return ApiResult.error("父部门ID不能是自己");
		}
		if (StringUtilsV2.isNotBlank(dep.getDepCode())) {
			Dep oldRole = depDao.getByDepCode(dep.getDepCode());
			if (oldRole != null && !dep.getDepId().equals(oldRole.getDepId())) {
				return ApiResult.error("部门编码已存在");
			}
		}
		verifyForm(dep);
		depDao.update(dep);
		return ApiResult.ok();
	}

	@LogAnnotation
	@DeleteMapping("/delete/{id}")
	@ApiOperation(value = "部门-物理删除")
	//@PreAuthorize("hasAuthority('sys:org:del')")
	public ApiResult<?> delete(@PathVariable String id) {
		if (StringUtilsV2.isBlank(id)) {
			return ApiResult.error("部门ID不能为空");
		}
		depDao.delete(id);
		return ApiResult.ok();
	}

	@LogAnnotation
	@DeleteMapping("/{id}")
	@ApiOperation(value = "部门-逻辑删除")
	//@PreAuthorize("hasAuthority('sys:org:del')")
	public ApiResult<?> deleteEditStatus(@PathVariable String id) {
		if (StringUtilsV2.isBlank(id)) {
			return ApiResult.error("部门ID不能为空");
		}
		depDao.updateStatus(Arrays.asList(id), Constant.DATA_STATUS_DELETE);
		return ApiResult.ok();
	}

	@LogAnnotation
	@DeleteMapping("/stop/{id}")
	@ApiOperation(value = "部门-停用")
	//@PreAuthorize("hasAuthority('sys:org:stop')")
	public ApiResult<?> stop(@PathVariable String id) {
		if (StringUtilsV2.isBlank(id)) {
			return ApiResult.error("部门ID不能为空");
		}
		depDao.updateStatus(Arrays.asList(id), Constant.DATA_STATUS_TYPE_STOP);
		return ApiResult.ok();
	}

	@PostMapping("/list")
	@ApiOperation(value = "部门-列表（分页）")
	//@PreAuthorize("hasAuthority('sys:dep:query')")
	public PageInfo<Dep> ListNew(@RequestBody DepWhere strCon) {
		PageHelper.startPage(strCon.getOffset(), strCon.getLimit());
		if (StringUtilsV2.isBlank(strCon.getSqlOrder())) {
			strCon.setSqlOrder("t.create_time desc ");
		}
		PageHelper.orderBy(strCon.getSqlOrder());
		List<Dep> list = depDao.DepList(strCon);
		PageInfo<Dep> result = new PageInfo<Dep>(list);
		return result;
	}

	@GetMapping("/listAll")
	@ApiOperation(value = "部门-列表（不分页）")
	//@PreAuthorize("hasAuthority('sys:dep:query')")
	public List<Dep> listAll() {
		return depDao.listAll();
	}

	/**
	 * 验证参数是否正确
	 */
	private void verifyForm(Dep dep) {
		// 上级部门id
		String parentId = dep.getParentId();
		// 没传父部门id默认为顶级部门
		if (StringUtilsV2.isBlank(parentId) || "0".equals(parentId)) {
			dep.setParentId("0");
			// 默认为顶级
			dep.setLevel(1);
		} else {
			Dep parentDep = depDao.getById(parentId);
			Integer parentLevel = parentDep.getLevel();
			if (parentLevel != null) {
				dep.setLevel(parentLevel + 1);
			}
		}
	}

	/**
	 * 获取某个机构下的部门树
	 * 
	 * @param id
	 * @return
	 */
	@GetMapping("/listByOrgId/{id}")
	//@PreAuthorize("hasAuthority('sys:dep:query')")
	@ApiOperation(value = "部门-获取某个机构下的部门树")
	public JSONArray listByOrgId(@PathVariable String id) {
		List<DepVO> areasAll = depDao.listByOrgId(id);
		JSONArray array = new JSONArray();
		setTree("0", areasAll, array/* ,null */);

		return array;
	}

	/**
	 * 区域树
	 * 
	 * @param pId
	 * @param areasAll
	 * @param array
	 */
	private void setTree(String pId, List<DepVO> lists,
			JSONArray array/* ,JSONObject parent */) {
		for (DepVO per : lists) {
			if (per.getParentId().equals(pId)) {
				String string = JSONObject.toJSONString(per);
				JSONObject parent = (JSONObject) JSONObject.parse(string);
				parent.put("createTime", CommUtil.formatLongDate(parent.get("createTime")));
				array.add(parent);
				if (lists.stream().filter(p -> p.getParentId().equals(per.getDepId())).findAny() != null) {
					JSONArray child = new JSONArray();
					parent.put("child", child);
					setTree(per.getDepId(), lists, child/* ,parent */);
					
					JSONArray children = new JSONArray();
					parent.put("children", child);
					setTree(per.getDepId(), lists, children/* ,parent */);
				}
			}
		}
	}

	@GetMapping("/listShordByOrgId/{id}")
	//@PreAuthorize("hasAuthority('sys:dep:query')")
	@ApiOperation(value = "部门-获取某个机构下的部门树(正常状态的)")
	public JSONArray listShordByOrgId(@PathVariable String id) {
		List<DepShordVO> areasAll = depDao.listShordByOrgId(id);
		JSONArray array = new JSONArray();
		setTreeShord("0", areasAll, array/* ,null */);

		return array;
	}
	
	@GetMapping("/listDepByOrgId/{id}")
	////@PreAuthorize("hasAuthority('sys:dep:query')")
	@ApiOperation(value = "部门-获取某个机构下的部门(正常状态的)")
	public List<DepShordVO> listDepByOrgId(@PathVariable String id) {
		List<DepShordVO> areasAll = depDao.listShordByOrgId(id);
		return areasAll;
	}
	
	/**
	 * 区域树
	 * 
	 * @param pId
	 * @param areasAll
	 * @param array
	 */
	private void setTreeShord(String pId, List<DepShordVO> lists,
			JSONArray array/* ,JSONObject parent */) {
		for (DepShordVO per : lists) {
			if (per.getParentId().equals(pId)) {
				String string = JSONObject.toJSONString(per);
				JSONObject parent = (JSONObject) JSONObject.parse(string);
				array.add(parent);
				if (lists.stream().filter(p -> p.getParentId().equals(per.getDepId())).findAny() != null) {
					JSONArray child = new JSONArray();
					parent.put("child", child);
					setTreeShord(per.getDepId(), lists, child/* ,parent */);
				}
			}
		}
	}
}
